﻿Imports System.Reflection
Imports System.Diagnostics.CodeAnalysis

''' <summary>
''' Library of copying functions
''' </summary>
''' <remarks>
''' Reference: http://stackoverflow.com/questions/1198886/c-sharp-using-reflection-to-copy-base-class-properties
''' </remarks>
Public NotInheritable Class Copier
    ''' <summary>
    ''' Generically copies the properties of one object to another.
    ''' </summary>
    ''' <typeparam name="T1">Source type</typeparam>
    ''' <typeparam name="T2">Target type</typeparam>
    ''' <param name="source">Source object</param>
    ''' <param name="target"></param>
    ''' <returns>Source object</returns>
    ''' <remarks></remarks>
    Public Shared Function CopyFrom(Of T1 As Class, T2 As Class)(ByVal source As T1, ByVal target As T2) As T1

        'Get the properties from each object
        Dim srcFields As PropertyInfo() = target.[GetType]().GetProperties(BindingFlags.Instance Or BindingFlags.[Public] Or BindingFlags.GetProperty)
        Dim destFields As PropertyInfo() = source.[GetType]().GetProperties(BindingFlags.Instance Or BindingFlags.[Public] Or BindingFlags.SetProperty)
        'Copy all matches
        For Each [property] In srcFields
            Dim dest = destFields.FirstOrDefault(Function(x) x.Name = [property].Name)
            If dest IsNot Nothing AndAlso dest.CanWrite Then
                dest.SetValue(source, [property].GetValue(target, Nothing), Nothing)
            End If
        Next

        Return source

    End Function

#Region "Example Usage"
    ''' <summary>
    ''' Example base class with a single property.
    ''' </summary>
    ''' <remarks></remarks>
    Private Class SelfCopyingBase

        Private myData As String
        ''' <summary>
        ''' Simple string data.
        ''' </summary>
        ''' <value></value>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Public Property Data() As String
            Get
                Return myData
            End Get
            Set(ByVal value As String)
                myData = value
            End Set
        End Property

    End Class
    ''' <summary>
    ''' Example derived class.
    ''' </summary>
    ''' <remarks></remarks>
    Private Class SelfCopying
        Inherits SelfCopyingBase
        ''' <summary>
        ''' Copy constructor.
        ''' </summary>
        ''' <param name="source"></param>
        ''' <remarks></remarks>
        Public Sub New(ByVal source As SelfCopyingBase)

            Copier.CopyFrom(Of SelfCopyingBase, SelfCopying)(source, Me)

        End Sub

    End Class

#End Region

End Class